﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TVGuide.Common;
using System.Text.RegularExpressions;
using TVGuide.DataAccess.Exceptions;
//using TVGuide.DataAccess.Repository;
using TVGuide.DataAccess;
using TVGuide.DataAccess.Common;
using TVGuide.DataAccess.Repository;
using System.IO;

namespace TVGuide.Parser
{
    ///<summary>
    /// Parses TV program information from UCOM. General URL for the schedule is http://ucom.am/hy/services/services-tv-channels.html?date=250
    /// </summary>

    public class UCOMParseEngineNew
    {
        private static int currentDay = DateTime.Now.Day;
        public static List<Program> ParseSpecificProgramFromFile(string filePath)
        {
            List<Program> tvProgramList = new List<Program>();
            StreamReader streamReader = new StreamReader(filePath);
            string ucomHTMLString = streamReader.ReadToEnd();
            streamReader.Close();
            string pattern = "<div class=\"result-header\">.*? <span class=\"light-green\">.*?(<div class=\"search-result\">|<meta name=\"Ajax-Update-Ids\")";
            Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase);
            MatchCollection chanalCollection = rgx.Matches(ucomHTMLString);
            foreach (Match item in chanalCollection)
            {
                string chanProgsString = item.Value;
                string chanProgPattern = "<div class=\"prog-name\">.*?</div>";
                string chanNameDatePattern = "<div class=\"result-header\">(.*?) <span class=\"light-green\">(.*?)</span></div>";
                string progTimePattern = "<span class=\"div-green-btn-l\">(.*?)</span>";
                Regex rgxProgNames = new Regex(chanProgPattern, RegexOptions.IgnoreCase);
                Regex rgxProgTimes = new Regex(progTimePattern, RegexOptions.IgnoreCase);
                int id;
                DateTime date = new DateTime();
                _getChannelIDandDate(out id, out date, chanNameDatePattern, chanProgsString);
                MatchCollection progNames = rgxProgNames.Matches(chanProgsString);
                MatchCollection progTimes = rgxProgTimes.Matches(chanProgsString);
                tvProgramList.AddRange(_getProgramList(progNames, progTimes, id, date));
            }
            return tvProgramList;
        }

        private static void _getChannelIDandDate(out int id, out DateTime date, string pattern, string chanProgs)
        {
            Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase);
            Match chanNameDate = rgx.Match(chanProgs);
            string channelName = chanNameDate.Groups[1].Value;
            string channelDate = chanNameDate.Groups[2].Value;
            id = _getChannelId(channelName);
            date = _parseToDateTime(channelDate);
        }

        private static DateTime _parseToDateTime(string dateTimeString)
        {

            string[] day = dateTimeString.Split(',');
            int parsingDay = Convert.ToInt32(day[1]);
            int month = DateTime.Now.Month;
            int year = DateTime.Now.Year;
            if ((DateTime.Now.Day - parsingDay) > 10)
            {
                //changing month, month transition happened
                if (month == 12)
                {
                    month = 1;
                    year = year + 1;
                }
                else
                {
                    month = month + 1;
                }
            }

            DateTime date = new DateTime(
                year,
                month,
                parsingDay
                );
            return date;
        }

        private static int _getChannelId(string channelName)
        {
            foreach (Enums.NewUcomChannels value in Enum.GetValues(typeof(Enums.NewUcomChannels)))
            {
                string enumMapped = value.ToString(); // space is mapped to _, only digits mapped to _digit
                if (_mapChannelName(channelName).ToLower() == enumMapped.ToLower())
                {
                    return (int)value;
                }
            }
            return -1;
        }

        private static string _mapChannelName(string unmappedChannelName)
        {
            string mappedChanName;
            if (unmappedChannelName == "1TV")
                return "_1TV";
            try
            {
                return mappedChanName = "_" + Convert.ToInt32(unmappedChannelName);
            }
            catch (FormatException ex)
            {
                return mappedChanName = unmappedChannelName.Trim().Replace(" ", "_");
            }

        }

        private static List<Program> _getProgramList(MatchCollection progNames, MatchCollection progTimes,
                                                    int id, DateTime date)
        {
            List<Program> _progList = new List<Program>();
            if (progNames.Count != progTimes.Count)
            {
                throw new InvalidOperationException();
            }
            int hour;
            int minute;
            int month = date.Month;
            int year = date.Year;
            DateTime correctedDate = date;
            for (int i = 0; i < progNames.Count; i++)
            {
                Utils.seperateTimeProgramName(progTimes[i].Value, out hour, out minute);
                Program tvProgram = new Program();
                tvProgram.Name = Utils.removeHTMLTags(progNames[i].Value).Trim();
                if (hour <= 7 && isLastDay(date))
                {
                    month = date.Month + 1;
                    if (month == 13)
                    {
                        month = 1;
                        year++;
                    }
                    correctedDate = new DateTime(
                    year,
                    month,
                    1,
                    hour,
                    minute,
                    0
                    );
                }
                else
                    if (hour <= 7)
                    {
                        correctedDate = date.AddDays(1);
                    }
                    else
                    {
                        correctedDate = date;
                    }



                tvProgram.Date = new DateTime(
                    date.Year,
                    correctedDate.Month,
                    correctedDate.Day,
                    hour,
                    minute,
                    0
                    );
                tvProgram.ChannelId = id;
                _progList.Add(tvProgram);
            }

            return _progList;
        }

        private static bool isLastDay(DateTime date)
        {
            int current = date.Month;
            if (date.AddDays(1).Month != current)
            {
                return true;
            }
            return false;
        }
    }
}